package com.xhwl.centiotdata.mq.comsumer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.account.AccountFactory;
import com.xhwl.centiotdata.handler.account.AccountHandler;
import com.xhwl.centiotdata.service.cent.IAccountCentService;
import com.xhwl.centiotdata.service.cent.IAuthAccountCentService;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.service.impl.AccountServiceImpl;
import com.xhwl.centiotdata.utils.AccountUtil;
import com.xhwl.common.dto.cent.sdata.AccountDTO;
import com.xhwl.common.dto.cent.sdata.PedestrianAuthTopicDTO;
import com.xhwl.common.enums.CategoryEnum;
import com.xhwl.common.pojo.cent.auth.AuthAccountMapping;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import com.xhwl.common.pojo.cent.sdata.Account;
import com.xhwl.common.pojo.cent.sdata.personnel.StaffDTO;
import com.xhwl.common.query.cent.device.ProductAccessQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;


/**
 * 账号处理
 *
 * @author pengjunming
 * @description
 * @date 2022/5/22 9:37
 */
@Component
@Slf4j
public class AccountConsumer {

    public static final String CREATE_STAFF_TOPIC = "cent-data-account-create";
    public static final String UPDATE_STAFF_TOPIC = "cent-data-account-update";
    public static final String DELETE_STAFF_TOPIC = "cent-data-account-delete";
    public static final String DELETE_STAFF_X_TOPIC = "cent-data-staff-delete";
    public static final String CAMPUS_JM_USER_INFO_AUTH_TOPIC = "campus-jm-user-info-auth";

    //  学生类型为1,教职工类型为3
    private static final Integer STUDENT_TYPE = 1;
    private static final Integer STAFF_TYPE = 3;
    //  在职状态为1,离职状态为0
    private static final String ON_JOB = "0";
    // 学生状态，1：在读 2：肆业 3：休学 4： 辍学 5：退学  6:已毕业
    private static final Integer IN_SCHOOL = 1;

    @Resource
    private IDeviceCentService iDeviceCentService;


    @Autowired
    private AccountUtil accountUtil;

    @Autowired
    private AccountServiceImpl accountService;
    @Autowired
    private IAccountCentService iAccountCentService;
    @Autowired
    IAuthAccountCentService authAccountCentService;

    @KafkaListener(topics = {CREATE_STAFF_TOPIC, UPDATE_STAFF_TOPIC, DELETE_STAFF_TOPIC}, groupId = "IOT-DATA-ACCOUNT")
    public void createAccount(ConsumerRecord<String, String> consumer) {
        log.info("topic:---------" + consumer.topic() + "----------------------------------------------------\n" + consumer.value());
        try {
            AtomicReference<AccountDTO> dto = new AtomicReference<>(JSONObject.parseObject(consumer.value(), AccountDTO.class));
            AccountDTO accountDTO = dto.get();
            List<Integer> projectIds = accountUtil.getProjectIds(accountDTO);
            log.info("-------------projectIds===" + accountDTO);
            for (Integer projectId : projectIds) {
                List<DeviceProjSupplierCategory> deviceProjSupplierCategories = iDeviceCentService.listProductAccess((short) 1, new ProductAccessQuery(projectId, CategoryEnum.DOOR.getId()));
                log.info("-------------deviceProjSupplierCategories.isNotEmpty===" + CollectionUtils.isNotEmpty(deviceProjSupplierCategories));
                if (CollectionUtils.isNotEmpty(deviceProjSupplierCategories)) {
                    log.info("-------------deviceProjSupplierCategories.size===" + deviceProjSupplierCategories.size());
                    deviceProjSupplierCategories.forEach(config -> {
                        AccountHandler invokeStrategy = AccountFactory.getInvokeStrategy(config.getProductId());
                        if (Objects.nonNull(invokeStrategy) && Objects.nonNull(accountDTO)) {
                            log.info("invokeStrategy：" + invokeStrategy.getClass().getSimpleName());
                            StaffDTO staffDTO = accountUtil.handleAccount(accountDTO);
                            log.info("账号同步：" + JSON.toJSONString(staffDTO));
                            if (staffDTO == null) {
                                return;
                            }
                            log.info("----------------------------开始消费----------------------------");
                            switch (consumer.topic()) {
                                case CREATE_STAFF_TOPIC:
                                    invokeStrategy.add(staffDTO, projectId, config);
                                    break;
                                case UPDATE_STAFF_TOPIC:
                                    invokeStrategy.update(staffDTO, projectId, config);
                                    break;
                                case DELETE_STAFF_TOPIC:
                                    invokeStrategy.delete(accountDTO, projectId, config);
                                    break;
                                default:
                                    break;
                            }
                        }else {
                            log.info("invokeStrategy.isNotNull：" + Objects.nonNull(invokeStrategy));
                            log.info("accountDTO.isNotNull：" + Objects.nonNull(accountDTO));
                        }
                    });
                }
            }
        } catch (Exception e) {
            log.error(consumer.topic() + " consume error data ：{}", e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 人员离职
     * @param consumer
     */
    @KafkaListener(topics = { DELETE_STAFF_X_TOPIC}, groupId = "IOT-DATA-ACCOUNT")
    public void deleteStaff(ConsumerRecord<String, String> consumer) {
        log.info("topic:---------" + consumer.topic() + "----------------------------------------------------\n" + consumer.value());
        try {
            AtomicReference<StaffDTO> dto = new AtomicReference<>(JSONObject.parseObject(consumer.value(), StaffDTO.class));
            StaffDTO staffDTO = dto.get();
            Account account = iAccountCentService.findById(staffDTO.getAccountId());
            AccountDTO accountDTO = new AccountDTO();
            BeanUtils.copyProperties(account,accountDTO);
            accountDTO.setProjectIds(staffDTO.getProjectIds());
            accountDTO.setEnterpriseIds(staffDTO.getEnterpriseId());
            List<Integer> projectIds = accountUtil.getProjectIds(accountDTO);
            log.info("-------------projectIds===" + accountDTO);
            for (Integer projectId : projectIds) {
                List<DeviceProjSupplierCategory> deviceProjSupplierCategories = iDeviceCentService.listProductAccess((short) 1, new ProductAccessQuery(projectId, CategoryEnum.DOOR.getId()));
                log.info("-------------deviceProjSupplierCategories.isNotEmpty===" + CollectionUtils.isNotEmpty(deviceProjSupplierCategories));
                if (CollectionUtils.isNotEmpty(deviceProjSupplierCategories)) {
                    log.info("-------------deviceProjSupplierCategories.size===" + deviceProjSupplierCategories.size());
                    deviceProjSupplierCategories.forEach(config -> {
                        AccountHandler invokeStrategy = AccountFactory.getInvokeStrategy(config.getProductId());
                        if (Objects.nonNull(invokeStrategy) && Objects.nonNull(accountDTO)) {
                            log.info("invokeStrategy：" + invokeStrategy.getClass().getSimpleName());
                            log.info("账号同步：" + JSON.toJSONString(staffDTO));
                            if (staffDTO == null) {
                                return;
                            }
                            log.info("----------------------------开始消费----------------------------");
                            switch (consumer.topic()) {
                                case DELETE_STAFF_X_TOPIC:
                                    log.info("----DELETE_STAFF_X_TOPIC----");
                                    invokeStrategy.delete(accountDTO, projectId, config);
                                    break;
                                default:
                                    break;
                            }
                        }else {
                            log.info("invokeStrategy.isNotNull：" + Objects.nonNull(invokeStrategy));
                            log.info("accountDTO.isNotNull：" + Objects.nonNull(accountDTO));
                        }
                    });
                }
            }
        } catch (Exception e) {
            log.error(consumer.topic() + " consume error data ：{}", e.getMessage());
            e.printStackTrace();
        }
    }

    // H5页面更新人脸信息
    @KafkaListener(topics = "cent-face-add-single", groupId = "iot-data")
    public void accountUpdate(ConsumerRecord<?, ?> record) {
        String recordStr = record.value().toString();
        log.info("recordStr:{}", recordStr);
        JSONObject jsonObject = JSON.parseObject(recordStr);
        Integer accountId = jsonObject.getInteger("accountId");
        Integer projectId = jsonObject.getInteger("projectId");
        // 查询住户人员信息
        List<AccountDTO> accountDTOList = accountService.queryAccount(projectId, Arrays.asList(accountId));
        AccountDTO accountDTO = accountDTOList.get(0);
        // 如果住户人员的手机号为空，就使用产权人的手机号
        StaffDTO staffOne = new StaffDTO();
        staffOne.setAccountId(accountId);
        staffOne.setName(accountDTO.getName());
        staffOne.setPhone(accountDTO.getPhone());

        // 修改人员的人脸信息
        List<DeviceProjSupplierCategory> deviceProjSupplierCategories = iDeviceCentService.listProductAccess((short) 1, new ProductAccessQuery(projectId, CategoryEnum.DOOR.getId()));
        if (CollectionUtils.isNotEmpty(deviceProjSupplierCategories)) {
            deviceProjSupplierCategories.forEach(config -> {
                AccountHandler invokeStrategy = AccountFactory.getInvokeStrategy(config.getProductId());
                if (Objects.nonNull(invokeStrategy)) {
                    //查询人员对应关系
                    AuthAccountMapping mapping = authAccountCentService.query(projectId,accountId,config.getProductId());
                    if (Objects.nonNull(mapping)){
                        log.info("cent-face-add-single update:{}",JSON.toJSONString(staffOne));
                        invokeStrategy.update(staffOne, projectId, config);
                    }
                }
            });
        }
    }

    @KafkaListener(topics = {CAMPUS_JM_USER_INFO_AUTH_TOPIC})
    public void campusAccount(ConsumerRecord<String, String> consumer) {
        log.error("topic:---------" + consumer.topic() + "-----------------------\n" + consumer.value());
        try {
            JSONObject jsonObject = JSON.parseObject(consumer.value());
            log.info("接收到的kafka消息为{}", jsonObject);
            // 封装JSON对象数据到业务DTO
            Integer userType = jsonObject.getInteger("userType");
            PedestrianAuthTopicDTO authDTO = handlePedestrianAuthTopicDTO(userType, jsonObject);
            log.info("userType{},authDTO{}", userType, authDTO);
            AccountDTO accountDTO = new AccountDTO();
            accountDTO.setId(authDTO.getAccountId());
            //  获取供应商设备
            List<DeviceProjSupplierCategory> deviceProjSupplierCategories = iDeviceCentService.listProductAccess((short) 1, new ProductAccessQuery(authDTO.getProjectId(), CategoryEnum.DOOR.getId()));
            log.info("deviceProjSupplierCategories{}", deviceProjSupplierCategories);
            if (CollectionUtils.isNotEmpty(deviceProjSupplierCategories)) {
                deviceProjSupplierCategories.forEach(config -> {
                    AccountHandler invokeStrategy = AccountFactory.getInvokeStrategy(config.getProductId());
                    // 学生类型
                    if (userType.equals(STUDENT_TYPE) && !authDTO.getEducateStatus().equals(IN_SCHOOL)) {
                        invokeStrategy.delete(accountDTO, authDTO.getProjectId(), config);
                        log.info("学生权限删除");
                    }
                    // 教职工类型
                    else if (userType.equals(STAFF_TYPE) && !authDTO.getIsLeave().equals(ON_JOB)) {
                        invokeStrategy.delete(accountDTO, authDTO.getProjectId(), config);
                        log.info("教职工权限删除");
                    }
                });
            }
        } catch (Exception e) {
            log.error(consumer.topic() + " consume error data ：{}", e.getMessage());
            e.printStackTrace();
        }
    }

    public PedestrianAuthTopicDTO handlePedestrianAuthTopicDTO(Integer userType, JSONObject jsonObject) {
        PedestrianAuthTopicDTO authDTO = new PedestrianAuthTopicDTO();
        if (userType.equals(STAFF_TYPE)) {
            authDTO.setProjectId(jsonObject.getInteger("projectId"));
            authDTO.setAccountId(jsonObject.getInteger("accountId"));
            authDTO.setName(jsonObject.getString("name"));
            authDTO.setOrgId(jsonObject.getInteger("orgId"));
            authDTO.setPersonNo(jsonObject.getString("personalNo"));
            if (StringUtils.isNotEmpty(jsonObject.getString("faceUrl"))) {
                authDTO.setFaceUrl(jsonObject.getString("faceUrl"));
            }
            authDTO.setPhone(jsonObject.getString("phone"));
            authDTO.setCardNum(jsonObject.getString("cardNo"));
            authDTO.setIsLeave(jsonObject.getString("isLeave"));
        } else if (userType.equals(STUDENT_TYPE)) {
            JSONObject student = (JSONObject) jsonObject.get("studentInfo");
            authDTO.setProjectId(student.getInteger("projectId"));
            authDTO.setAccountId(student.getInteger("accountId"));
            authDTO.setName(student.getString("name"));
            authDTO.setOrgId(student.getInteger("orgId"));
            authDTO.setPersonNo(student.getString("personalNo"));
            if (StringUtils.isNotEmpty(student.getString("faceUrl"))) {
                authDTO.setFaceUrl(student.getString("faceUrl"));
            }
            authDTO.setPhone(student.getString("phone"));
            authDTO.setCardNum(student.getString("cardNo"));
            authDTO.setEducateStatus(student.getInteger("educateStatus"));
        }
        return authDTO;
    }
}
